// testgo project main.go
package main

import (
	"net/url"
	"strings"
	"time"
	"path/filepath"
	"3rd/mongo"
	"crypto/aes"
	"crypto/cipher"
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"os"
		"github.com/astaxie/beego/logs"
)

func main() {
	var urlStr string = "羽毛"
    //l, _ := url.ParseQuery(urlStr)
    l3, err := url.Parse(urlStr)
	fmt.Println(l3.String(), err)
	l4, err := url.Parse(l3.String())
	fmt.Println(l4.String(), err)
    //fmt.Println(l3.Query().Encode())
	return
	
	Log := logs.NewLogger(10000)
	Log.SetLogger("console", "")
	Log.EnableFuncCallDepth(true)
	

	// TODO: hack
	dir := filepath.Dir(os.Args[0])
	path := filepath.Join(dir, "waterblabla.log")    
	path = strings.Replace(path, `\`, "/", -1)
	Log.SetLogger("file", `{"filename":"`+ path + `"}`)
	
	time.Sleep(4*time.Second)
	
}

func main0() {
	mongo.InitMongo("root:123456@192.168.0.30:27017")
	mongo.DO("order", "order", func(c *mgo.Collection) error  {
		// 送水工某个时间段共送了多少桶水
		n ,_ := c.Find(bson.M{
		"station.qid":"cfe56c575b6c3ab86089a1959b5aa29c", 
		"postman.mobilePhone": "18530950471",
		"created": bson.M{"$gte": 1446095902, "$lt": 1446096872},
		}).Count()
		fmt.Println("count:", n)
		// 送水工某个时间段每天送了多少桶水
		pipe := c.Pipe([]bson.M{
		{"$match": bson.M{"state":4,"postman._id": "3cfb0c767651da86b2d5a033ffa6a78f","created": bson.M{"$gte": 0, "$lt": 14460968720}}},
		{"$group": bson.M{ "_id": nil, "count": bson.M{ "$sum" :"$sentBuckets" } }} ,
		/*{"$match": bson.M{
		"station.qid":"cfe56c575b6c3ab86089a1959b5aa29c", 
		"postman.mobilePhone": "18530950471",
		"created": bson.M{"$gte": 1446095902, "$lt": 1446096872},
		}},
		{ "$project" : bson.M{ "_id" : 1  }},
		{ "$group": bson.M{ "_id": bson.M{"$mod": []interface{}{bson.M{"$subtract":[]interface{}{"$created", 1970}}, 86400} }, "count": bson.M{ "$sum" :"$sentBuckets" } } },*/
		})
		var out []bson.M
		 pipe.All(&out)
		fmt.Println(len(out), out)
		return nil
	})
	
	return
	id := bson.ObjectIdHex("55ed26a4856994d28cde675d")
	fmt.Println(id.Time().Unix())
	return

	aesEnc := AesEncrypt{}
	arrEncrypt, err := aesEnc.Encrypt("abcde")
	if err != nil {
		fmt.Println(arrEncrypt)
		return
	}
	fmt.Println("encrypt:", string(arrEncrypt))
	strMsg, err := aesEnc.Decrypt(arrEncrypt)
	if err != nil {
		fmt.Println(arrEncrypt)
		return
	}
	fmt.Println("Decrypt:", strMsg)
}

type AesEncrypt struct {
}

func (this *AesEncrypt) getKey() []byte {
	strKey := "abcdefghijklmnopkrstuvwsyz012345"
	keyLen := len(strKey)
	if keyLen < 16 {
		panic("res key 长度不能小于16")
	}
	arrKey := []byte(strKey)
	if keyLen >= 32 {
		//取前32个字节
		return arrKey[:32]
	}
	if keyLen >= 24 {
		//取前24个字节
		return arrKey[:24]
	}
	//取前16个字节
	return arrKey[:16]
}

//加密字符串
func (this *AesEncrypt) Encrypt(strMesg string) ([]byte, error) {
	key := this.getKey()
	var iv = []byte(key)[:aes.BlockSize]
	encrypted := make([]byte, len(strMesg))
	aesBlockEncrypter, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, iv)
	aesEncrypter.XORKeyStream(encrypted, []byte(strMesg))
	return encrypted, nil
}

//解密字符串
func (this *AesEncrypt) Decrypt(src []byte) (strDesc string, err error) {
	defer func() {
		//错误处理
		if e := recover(); e != nil {
			err = e.(error)
		}
	}()
	key := this.getKey()
	var iv = []byte(key)[:aes.BlockSize]
	decrypted := make([]byte, len(src))
	var aesBlockDecrypter cipher.Block
	aesBlockDecrypter, err = aes.NewCipher([]byte(key))
	if err != nil {
		return "", err
	}
	aesDecrypter := cipher.NewCFBDecrypter(aesBlockDecrypter, iv)
	aesDecrypter.XORKeyStream(decrypted, src)
	return string(decrypted), nil
}

func main1() {
	//fmt.Println("Hello World!")
	var rest []map[string]interface{}
	err := DO("provider", "provider", func(c *mgo.Collection) (err error) {
		return c.Find(nil).Select(bson.M{"company": 1, "_id": 1}).All(&rest)
	})
	fmt.Println(err, rest)
}

func main2() {

}

var sess *mgo.Session

func session() *mgo.Session {

	if sess == nil {
		var err error
		// TODO:
		if sess, err = mgo.Dial("root:123456@localhost:27017"); err != nil {
			panic(err)
		}
	}
	return sess.Clone()
}

func DO(db, col string, f func(*mgo.Collection) error) error {
	s := session()
	defer func() {
		s.Close()
	}()

	return f(s.DB(db).C(col))
}

/*
func (this *Mongo) FindOne(selector bson.M, content interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(selector).One(content)
	})
}

func (this *Mongo) SelectOne(query, selector bson.M, content interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(query).One(selector)
	})
}

func (this *Mongo) FindAll(selector bson.M, out interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(selector).All(out)
	})
}

func (this *Mongo) FindAllWithLimit(selector bson.M, count int, out interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(selector).Limit(count).All(out)
	})
}

func (this *Mongo) FindAllWithLimitSort(selector bson.M, count int, out interface{}, sort string) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(selector).Sort(sort).Limit(count).All(out)
	})
}

func (this *Mongo) SelectAll(query, selector bson.M, out interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Find(query).Select(selector).All(out)
	})
}

func (this *Mongo) Create(content interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Insert(content)
	})
}

func (this *Mongo) Delete(selector bson.M) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		_, err = c.RemoveAll(selector)
		return
	})
}

func (this *Mongo) Update(selector bson.M, content interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		return c.Update(selector, content)
	})
}

func (this *Mongo) Upsert(selector bson.M, content interface{}) error {
	return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
		_, err = c.Upsert(selector, content)
		return err
	})
}

func (this *Mongo) BulkInsert(docs []interface{}) error {

		return DO(this.Db, this.Col, func(c *mgo.Collection) (err error) {
			bulk := c.Bulk()
			for _, doc := range docs {
				bulk.Insert(doc)
			}
			_, err = bulk.Run()
			return err
		})

	return nil
}*/
